/*
 *	继承inherit
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Person
{
	protected:	//允许在子类中直接访问
		string name;
	public:
		void setname(const char* str1)
		{
			name=str1;
		}
		void eat(string food)
		{
			cout << name << " eat " << food << endl;
		}
		void speak(string words)
		{
			cout << name << " speak:\"" << words << endl;
		}
};

class Teacher : public Person
{
	string course;
	public:
	void teach(string someclass)
	{
		cout << name << " at " << someclass << " teach " 
			<< course << endl;
	}
	void setcourse(string c)
	{
		course=c;
	}
};

int main()
{
	Person a;
	a.setname("furong");
	a.eat("yu");
	a.speak("I ...");

	cout << endl;
	Teacher c;
	c.setname("fu");
	c.speak("YOU ...");
	c.setcourse("c++");
	c.teach("2.5");
	return 0;
}

/*
 *	继承的构造，析构
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Person
{
	string name;
	public:
	const string& getName()
	{
		return name;
	}
	Person(const char* str1):name(str1)
	{
		cout << "Person(" << str1 << ")" << endl;
	}
	~Person()
	{
		cout << "~Person()" << endl;
	}
	void show()
	{
		cout << "hello ,I am " << name << endl;
	}
};
class Teacher : public Person
{
	string course;
	public:
	Teacher(const char* n,const char* c)
		:course(c),Person(n)
	{
		cout << "Teacher(" << n << ' ' << c << ")\n";
	}
	~Teacher()
	{
		cout << "~Teacher()" << endl;
	}
	void show()//回隐藏来自父类的同名函数
	{
		cout << "every one! I am " << getName() << endl;
	}
};
int main()
{
	Teacher a("yang","c++");
	a.show();//调用子类的show函数
	return 0;
}

/*
 *	多重继承
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Phone
{
	public:
		Phone()
		{
			cout << "Phone() " << endl;
		}
		void call(string num)
		{
			cout << "call " << num << endl;
		}
};
class Camera
{
	public:
		Camera()
		{
			cout << "Camera()" << endl;
		}
		void takephoto(string target)
		{
			cout << "takephoto " << target << endl;
		}
};

class CellPhone : public Phone,public Camera
{
	public:
		CellPhone():Camera(),Phone()//零初始化
	{//按照继承顺序调用父类构造函数
		cout << "CellPhone()" << endl;
	}
};
int main()
{
	CellPhone nokia;
	nokia.call("1234");
	nokia.takephoto("furong");
	return 0;
}

/*
 *	虚继承
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Person
{
	string name;
	public:
	Person(const char* str1):name(str1)
	{
		cout << "Person(" << str1 << ")" << endl;
	}
	const string& Name()const
	{
		return name;
	}
};

class Teacher : virtual public Person
{
	string course;
	public:
	Teacher(const char* n,const char* c):course(c),Person(n)
	{
		cout << "Teacher(" << n << ' ' << c <<")\n";
	}
	void teach(const char* c)
	{
		cout << Name() << " at " << " teach " << course << endl;
	}
};
class Student : virtual public Person
{
	string stuID;
	public:
	Student(const char* n,const char* s):stuID(s),Person(n)
	{
		cout << "Student(" << n << ' ' << s << ")\n";
	}
	void listen(const char* room)
	{
		cout << Name() << " at " << room << "listem" << endl;
	}
};

class DoubleMan : public Student,public Teacher
{
	public:
		DoubleMan(const char* n,const char* c,const char* id)
			:Teacher(n,c),Student(n,id),Person(n)
		{
			cout << "DoubleMan(" << n << ' ' << c << ' ' << id << ")\n";
		}
};

int main()
{
	DoubleMan a("quan","c++","09");
	a.teach("fu");
	a.listen("csd");
	cout << a.Name() << endl;
	return 0;
}

/*
 *	多态
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Vehicle
{
	public:
		virtual void stop()//虚函数
		{
			cout << "stop." << endl;
		}
};
class Car : public Vehicle
{
	public:
		void stop()
		{
			cout << "Car stop." << endl;
		}
};
class Bike : public Vehicle
{
	public:
		void stop()
		{
			cout << "Bike stop." << endl;
		}
};

class Light	//交通信号灯
{
	public:
		void stopvehicle(Vehicle& v)
		{
			v.stop();
		}
};

int main()
{
	Light light;
	Car bmw;
	Bike yj;
	light.stopvehicle(bmw);
	light.stopvehicle(yj);
	return 0;
}

/*
 *	虚函数表
 *		 */
#include<iostream>

using namespace std;

class Animal
{
	public:
			virtual void eat(){cout << "animal food." << endl;}
				virtual void shout(){cout << "animal voice." << endl;}
					void sleep()
							{
										cout << "animal sleep"<<endl;
											}
};
class Cat : public Animal
{
	public:
			void eat(){cout << "mouse." <<endl;}
				void shout(){cout << "miao~" <<endl;}
};
class Dog : public Animal
{
	public:
			void eat(){cout << "meat." <<endl;}
				void shout(){cout << "wang~" <<endl;}
					void sleep()
							{
										cout << "dog sleep" <<endl;
											}
};
class Jiafei : public Cat
{
	public:
			void eat(){cout<<"noodle."<<endl;}
				void shout(){cout<<"speak."<<endl;}
};
class Person
{
	public: 
		void play(Animal& a)
		{
			a.eat();
			a.shout();
			a.sleep();
		}
};

int main()
{
	//cout << sizeof(Animal) << endl;//增加4字节虚函数表指针的空间
	Dog d;
	Jiafei j;
	Person p;
	p.play(d);
	p.play(j);

	return 0;

}

/*
 *	父子类转换
 *		 */
#include<iostream>

using namespace std;

class Person
{
	public:
		virtual void show()
		{}
};
class Teacher : public Person
{};
class Student : public Person
{};
class CppTeacher : public Teacher
{};

class Computer
{
	public:
		void start()
		{}
};
class Notebook : public Computer
{};

class Company
{
	public:
		void test(Person* p)
		{
			Student* p1=dynamic_cast<Student*>(p);
			if(p1)
			{cout<<"student"<<endl;}
			Teacher* p2=dynamic_cast<Teacher*>(p);
			if(p2)
			{cout<<"teacher"<<endl;}
			CppTeacher* p3=dynamic_cast<CppTeacher*>(p);
			if(p3)
			{cout<<"cpp teacher"<<endl;}
		}
};

int main()
{
	Computer* c=new Notebook();
	//dynamic_cast<Notebook*>(c);//错误，无虚函数
	Person* ps=new Student();
	Person* pt=new Teacher();
	Person* pc=new CppTeacher();

	Company tar;
	tar.test(ps);	
	tar.test(pt);	
	tar.test(pc);	
	//delete ...
	return 0;

}

/*
 *	typeid
 *		 */
#include<iostream>
#include<typeinfo>

using namespace std;

class Person
{
	virtual void f()//引用多态特性
	{}
};
class Student : public Person
{};

int main()
{
	int a;unsigned u;double b;
	Person p;
	Student s;
	cout<< typeid(a).name() << ' ' 
		<< typeid(u).name() << ' '
		<< typeid(b).name() << ' '
		<< typeid(p).name() << ' '
		<< typeid(s).name() << endl;
	Person* s1=new Student();
	cout<< typeid(*s1).name() << endl;
	cout<< boolalpha << (typeid(*s1)==typeid(Student)) << endl;
	return 0;
}

/*
 *	纯虚函数
 *		 */
#include<iostream>
#include<string>

using namespace std;

class Graph
{
	int x;
	int y;
	public:
	Graph(int x,int y):x(x),y(y)
	{}
	virtual double area()=0; //纯虚函数
	void show()
	{
		cout << Type() << " position(" << x << ',' 
			<< y << "),area:" << area() << endl;
	}
	virtual string Type()=0;
};
class Rect : public Graph
{
	int w;
	int h;
	public:
	Rect(int x,int y,int w,int h):Graph(x,y),w(w),h(h)
	{}
	double area()
	{
		return w*h;
	}
	string Type()
	{
		return "Rect";
	}

};
class Circle : public Graph
{
	int r;
	public:
	Circle(int x,int y,int r):Graph(x,y),r(r)
	{}
	double area()
	{
		return 3.14*r*r;
	}
	string Type()
	{
		return "Circle";
	}
};
class Computer
{
	public:
		static void usegrahp(Graph& g)
		{
			g.show();
		}
};

int main()
{
	Circle c(8,8,10);
	Rect r(0,0,20,5);
	Computer::usegrahp(c);
	Computer::usegrahp(r);
	return 0;
}

